package text

import (
	"encoding/binary"
	"fmt"
	"strings"
	"inkjet168x-sdk-go/sdk/protocol/common"
)

// Protocol 文本协议实现
type Protocol struct {
	// 协议头部
	StartBytes   [4]uint8  // 起始位: 0x5A 0x4B 0x43 0x54
	Sequence     uint16    // 序列号
	PacketType   uint8     // 数据包类型: 0x01
	PacketLength uint32    // 数据包长度
	
	// 字体设置
	FontName    [32]byte  // 字体名称，UTF8编码，32字节
	FontSize    uint32    // 字号，范围12-1000
	FontWidth   uint32    // 字宽，范围12-1000
	CharSpacing uint32    // 字间隔，范围0-999999
	Rotation    uint32    // 旋转角度，范围0-90
	Bold        uint32    // 加粗，0不加粗，其他值加粗
	Italic      uint32    // 斜体，0正常，其他值斜体
	Style       uint32    // 样式，0x00实体/0x01圆点阵/0x02方点阵/0x03删除体
	
	// 位置信息
	Position common.Position
	
	// 文本内容
	Text         []byte    // 文本内容，UTF8编码，长度1-103200
	Reserved     [4]uint8  // 保留字节
	Checksum     uint16    // CRC16校验和
	StopBytes    [2]uint8  // 停止位: 0x0D 0x0A
}

// NewProtocol 创建新的文本协议实例
func NewProtocol() common.Protocol {
	tp := &Protocol{
		StartBytes: [4]uint8{common.StartByte1, common.StartByte2, common.StartByte3, common.StartByte4},
		PacketType: uint8(common.ProtocolTypeText),
		StopBytes:  [2]uint8{common.StopByte1, common.StopByte2},
		// 设置默认值
		FontSize:  150,  // 默认字号150
		FontWidth: 150,  // 默认字宽150
		Style:     uint32(common.StyleSolid), // 默认实体样式
	}
	// 设置默认字体名称
	tp.SetFontName("simhei.ttf")
	return tp
}

// GetType 获取协议类型
func (tp *Protocol) GetType() common.ProtocolType {
	return common.ProtocolTypeText
}

// Marshal 序列化为字节数组
func (tp *Protocol) Marshal() ([]byte, error) {
	// 计算数据包长度 (不包括起始位、序列号、包类型、包长度字段本身)
	tp.PacketLength = uint32(len(tp.Text) + 72) // 字体名称+字体设置+位置+文本+保留+校验+停止位
	
	// 计算需要的总字节数
	totalSize := 4 + 2 + 1 + 4 + 32 + 28 + 8 + len(tp.Text) + 4 + 2 + 2
	data := make([]byte, totalSize)
	
	offset := 0
	
	// 起始位
	copy(data[offset:], tp.StartBytes[:])
	offset += 4
	
	// 序列号 (大端序)
	binary.BigEndian.PutUint16(data[offset:], tp.Sequence)
	offset += 2
	
	// 数据包类型
	data[offset] = tp.PacketType
	offset += 1
	
	// 数据包长度 (小端序)
	binary.LittleEndian.PutUint32(data[offset:], tp.PacketLength)
	offset += 4
	
	// 字体名称
	copy(data[offset:], tp.FontName[:])
	offset += 32
	
	// 字体设置 (小端序)
	binary.LittleEndian.PutUint32(data[offset:], tp.FontSize)
	offset += 4
	binary.LittleEndian.PutUint32(data[offset:], tp.FontWidth)
	offset += 4
	binary.LittleEndian.PutUint32(data[offset:], tp.CharSpacing)
	offset += 4
	binary.LittleEndian.PutUint32(data[offset:], tp.Rotation)
	offset += 4
	binary.LittleEndian.PutUint32(data[offset:], tp.Bold)
	offset += 4
	binary.LittleEndian.PutUint32(data[offset:], tp.Italic)
	offset += 4
	binary.LittleEndian.PutUint32(data[offset:], tp.Style)
	offset += 4
	
	// 位置信息 (小端序)
	binary.LittleEndian.PutUint32(data[offset:], tp.Position.X)
	offset += 4
	binary.LittleEndian.PutUint32(data[offset:], tp.Position.Y)
	offset += 4
	
	// 文本内容
	copy(data[offset:], tp.Text)
	offset += len(tp.Text)
	
	// 保留字节
	copy(data[offset:], tp.Reserved[:])
	offset += 4
	
	// 计算校验和 (不包括校验和字段本身和停止位)
	tp.Checksum = common.CalculateChecksum(data[11:offset])
	binary.LittleEndian.PutUint16(data[offset:], tp.Checksum)
	offset += 2
	
	// 停止位
	copy(data[offset:], tp.StopBytes[:])
	
	return data, nil
}

// SetSequence 设置序列号
func (tp *Protocol) SetSequence(seq uint16) {
	tp.Sequence = seq
}

// GetSequence 获取序列号
func (tp *Protocol) GetSequence() uint16 {
	return tp.Sequence
}

// Unmarshal 从字节数组反序列化
func (tp *Protocol) Unmarshal(data []byte) error {
	if len(data) < 67 { // 最小包长度
		return fmt.Errorf("数据包太短: %d 字节", len(data))
	}
	
	offset := 0
	
	// 起始位
	copy(tp.StartBytes[:], data[offset:offset+4])
	offset += 4
	
	// 序列号
	tp.Sequence = binary.BigEndian.Uint16(data[offset:])
	offset += 2
	
	// 数据包类型
	tp.PacketType = data[offset]
	offset += 1
	
	// 数据包长度
	tp.PacketLength = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	
	// 字体名称
	copy(tp.FontName[:], data[offset:offset+32])
	offset += 32
	
	// 字体设置
	tp.FontSize = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	tp.FontWidth = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	tp.CharSpacing = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	tp.Rotation = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	tp.Bold = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	tp.Italic = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	tp.Style = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	
	// 位置信息
	tp.Position.X = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	tp.Position.Y = binary.LittleEndian.Uint32(data[offset:])
	offset += 4
	
	// 文本内容长度
	textLength := len(tp.Text)
	if offset+textLength > len(data) {
		return fmt.Errorf("无效的文本长度: %d", textLength)
	}

	fmt.Printf("数据包长度 (%d 字节):\n", textLength)

	tp.Text = make([]byte, textLength)
	copy(tp.Text, data[offset:offset+textLength])
	offset += textLength
	
	// 保留字节
	copy(tp.Reserved[:], data[offset:offset+4])
	offset += 4
	
	// 校验和
	tp.Checksum = binary.LittleEndian.Uint16(data[offset:])
	offset += 2
	
	// 停止位
	copy(tp.StopBytes[:], data[offset:offset+2])
	
	return nil
}

// Validate 验证协议参数
func (tp *Protocol) Validate() error {
	// 验证字号
	if err := common.ValidateRange(tp.FontSize, 12, 1000, "字号"); err != nil {
		return err
	}
	
	// 验证字宽
	if err := common.ValidateRange(tp.FontWidth, 12, 1000, "字宽"); err != nil {
		return err
	}
	
	// 验证字间隔
	if err := common.ValidateRange(tp.CharSpacing, 0, 999999, "字间隔"); err != nil {
		return err
	}
	
	// 验证旋转角度
	if err := common.ValidateRange(tp.Rotation, 0, 90, "旋转角度"); err != nil {
		return err
	}
	
	// 验证位置
	if err := common.ValidateRange(tp.Position.X, 0, 999999, "横坐标"); err != nil {
		return err
	}
	if err := common.ValidateRange(tp.Position.Y, 0, 999999, "纵坐标"); err != nil {
		return err
	}
	
	// 验证文本长度
	if err := common.ValidateTextLength(tp.Text, 1, 103200, "文本内容"); err != nil {
		return err
	}
	
	return nil
}

// String 返回协议的字符串表示
func (tp *Protocol) String() string {
	fontName := strings.TrimRight(string(tp.FontName[:]), "\x00")
	text := string(tp.Text)
	if len(text) > 20 {
		text = text[:17] + "..."
	}
	
	return fmt.Sprintf("TextProtocol{Seq:%d Font:%s Size:%d Pos:%s Text:\"%s\"}",
		tp.Sequence, fontName, tp.FontSize, tp.Position.String(), text)
}

// SetFontName 设置字体名称
func (tp *Protocol) SetFontName(fontName string) {
	// 清空字体名称数组
	for i := range tp.FontName {
		tp.FontName[i] = 0
	}
	
	// 复制字体名称，最多31字节（保留一个字节作为结束符）
	fontBytes := []byte(fontName)
	copyLen := len(fontBytes)
	if copyLen > 31 {
		copyLen = 31
	}
	copy(tp.FontName[:], fontBytes[:copyLen])
}

// SetBold 设置加粗
func (tp *Protocol) SetBold(bold bool) {
	if bold {
		tp.Bold = 1
	} else {
		tp.Bold = 0
	}
}

// SetItalic 设置斜体
func (tp *Protocol) SetItalic(italic bool) {
	if italic {
		tp.Italic = 1
	} else {
		tp.Italic = 0
	}
}

// SetPosition 设置位置
func (tp *Protocol) SetPosition(x, y uint32) {
	tp.Position.X = x
	tp.Position.Y = y
}

// SetText 设置文本内容
func (tp *Protocol) SetText(text string) {
	tp.Text = []byte(text)
}

// SetFontSize 设置字号
func (tp *Protocol) SetFontSize(fontSize uint32) {
	tp.FontSize = fontSize
}

// SetFontWidth 设置字宽
func (tp *Protocol) SetFontWidth(fontWidth uint32) {
	tp.FontWidth = fontWidth
}

// SetCharSpacing 设置字间隔
func (tp *Protocol) SetCharSpacing(charSpacing uint32) {
	tp.CharSpacing = charSpacing
}

// SetRotation 设置旋转角度
func (tp *Protocol) SetRotation(rotation uint32) {
	tp.Rotation = rotation
}

// SetStyle 设置样式
func (tp *Protocol) SetStyle(style uint32) {
	tp.Style = style
}